﻿// 1201. 丑数 III.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>


using namespace std;
/*
* https://leetcode.cn/problems/ugly-number-iii/description/
* 
给你四个整数：n 、a 、b 、c ，请你设计一个算法来找出第 n 个丑数。
丑数是可以被 a 或 b 或 c 整除的 正整数 。


示例 1：
输入：n = 3, a = 2, b = 3, c = 5
输出：4
解释：丑数序列为 2, 3, 4, 5, 6, 8, 9, 10... 其中第 3 个是 4。

示例 2：
输入：n = 4, a = 2, b = 3, c = 4
输出：6
解释：丑数序列为 2, 3, 4, 6, 8, 9, 10, 12... 其中第 4 个是 6。

示例 3：
输入：n = 5, a = 2, b = 11, c = 13
输出：10
解释：丑数序列为 2, 4, 6, 8, 10, 11, 12, 13... 其中第 5 个是 10。

示例 4：
输入：n = 1000000000, a = 2, b = 217983653, c = 336916467
输出：1999999984

提示：
1 <= n, a, b, c <= 10^9
1 <= a * b * c <= 10^18
本题结果在 [1, 2 * 10^9] 的范围内
*/


class Solution {
public:
    int gn;

    int gcd(int a, int b) {
        if (b == 0) return a;
        return gcd(b, a % b);
    }

    bool check(long long x ,int a, int b , int c) {
        //当前X 有多少个 a b c的倍数
        long long lcmab = 1LL * a * b / gcd(a, b);
        long long lcmbc = 1LL * c * b / gcd(c, b);
        long long lcmac = 1LL * a * c / gcd(a, c);
        long long lcmabc = 1LL * lcmab *c / gcd(lcmab, c);

        long long res = x / a + x / b + x / c - x / lcmab - x / lcmac - x / lcmbc + x / lcmabc;
        return  res >= gn;
    }

    int nthUglyNumber(int n, int a, int b, int c) {
        gn = n;
        long long l = 1; long long r = 1e18+10;
        while (l < r) {
            long long mid = (l + r) >> 1;
            if (check(mid,a,b,c)) {
                r = mid;
            }
            else {
                l = mid + 1;
            }
        }

        return l;
    }
};

int main()
{
    Solution s;
    cout << s.nthUglyNumber(3,2,3,5) << endl;
    cout << s.nthUglyNumber(4, 2, 3, 4) << endl;
    cout << s.nthUglyNumber(5, 2, 11, 13) << endl;
    cout << s.nthUglyNumber(1000000000, 2, 217983653, 336916467) << endl;


	return 0;
}

 